#include "waveformwidget.h"
#include <QPainter>
#include <iostream>
#include <fstream>
#include <cmath>

using namespace std;

WaveformWidget::WaveformWidget(QWidget *parent ) : QWidget(parent)
{
    // let plot data point to null
    this->plotDataUp = NULL;
    this->plotDataDown = NULL;
    	
	cursor = new CursorWidget(this);
	cursor->show();
	
	this->player = SoundPlayer::getInstance();
}

WaveformWidget::~WaveformWidget()
{
	// if one is set, delete all
    if( this->plotDataUp )
    {
        delete this->plotDataUp;
        delete this->plotDataDown;
    }
}

// gets triggered by the OS whenever the widget needs to be repainted
void WaveformWidget::paintEvent( QPaintEvent* event)
{
    QPainter painter(this);

    painter.setPen(Qt::gray);

    // fill widget with white bg
    painter.fillRect ( 0, 0, this->width(), this->height(), QColor("white"));
	 
	// draw middle line
	painter.drawLine( 0, (this->height()/2), this->width(), (this->height()/2));

	// scale the values to fit in the window 
    double scaleConstant = this->getMaxBitdepthValue() / (this->height()/2);
    int yPosLineEndUp;   // saves the y position where the line ends upwards
    int yPosLineEndDown; // saves the y position where the line ends downwards

    if ( (this->plotDataUp  != NULL) && (this->plotDataDown != NULL))
    {
        painter.setPen( Qt::red );

        for(int i=0; i < this->width(); i++)
        {            
            yPosLineEndUp   = (this->height()/2) - (plotDataUp[i]/scaleConstant);
            yPosLineEndDown = (this->height()/2) - (plotDataDown[i]/scaleConstant);

            painter.drawLine(i, (this->height()/2), i, yPosLineEndUp);
            painter.drawLine(i, (this->height()/2), i, yPosLineEndDown);
        }
    }
}

QSize WaveformWidget::sizeHint() const
{
    return this->size();
}

// getters and setters for the plotData
void WaveformWidget::setPlotDataUp ( int* plotDataUp )
{
	this->plotDataUp = plotDataUp;
	this->update();
}

void WaveformWidget::setPlotDataDown ( int* plotDataDown )
{
	this->plotDataDown = plotDataDown;
	this->update();
}

int* WaveformWidget::getPlotDataUp () const
{
	return this->plotDataUp;
}

int* WaveformWidget::getPlotDataDown() const
{
	return this->plotDataDown;
}

// calculate the maximum possible value depending on the 
// bitdepth of the given file
void WaveformWidget::setMaxBitdepthValue ( int bitdepth )
{
	this->maxBitdepthValue = (int) (pow(2.0, (bitdepth-1)));
}

int WaveformWidget::getMaxBitdepthValue ()
{
	return this->maxBitdepthValue;
}

void WaveformWidget::mousePressEvent(QMouseEvent* event)
{
	// we don't do something when no sound is already loaded and ready
	Phonon::State state = this->player->getPlayerObject()->state();
	
	if( state == Phonon::PlayingState || state == Phonon::BufferingState || state == Phonon::PausedState)
	{
	
		QPoint currentPos = this->cursor->pos();	
		QPoint mouseclickpoint = event->pos();
	
		// move the cursor to the clicked position
		this->cursor->move(mouseclickpoint.x(), currentPos.y());
	
		// get the total playing time (in ms) of the audio file
		qint64 totalTime = this->player->getPlayerObject()->totalTime();
		int jumpToPos = mouseclickpoint.x() * (totalTime/this->width());
		
		this->player->getPlayerObject()->seek(jumpToPos);
	}
}


